<?php

/**
 * You !
 * @author Cyril
 */
class Joueur {

    /**
     * Nom du joueur
     * @var string Identifiant d'un joueur. Unique dans la base de donnée 
     */
    private $nomjoueur;
    /**
     *  Dernier evenement vu par l'utilisateur
     * @var int
     */
    private $idevenement = 0;
    
    /**
     *  Partie auquel le joueur est associé
     * @var int idPartie 
     */
    private $idpartie = null;
    /**
     *
     * @var string(32) Chaine de caractères hexa 
     */
    private $token;
    /**
     *  DB Sqlite associé a l'objet
     * @var SQLITE_resource 
     */
    private $db;

    private $place=null;
    
    /**
     *  Cette fonction récupère le joueur portant ce nom. Si le joueur est introuvable, elle l'inserera dans la base de donnée
     * @param string $nomjoueur Nom du joueur
     */
    public function __construct($nomjoueur, $db) {
        $this->db = $db;
        $nomjoueur = mysql_real_escape_string($nomjoueur);
        $jrs = mysql_query("Select * from joueur where nomjoueur='$nomjoueur'");
        if ($jrs && $d = mysql_fetch_array($jrs)) {
            $this->idevenement = intval($d['idevenement']);
            $this->idpartie = intval($d['idpartie']);
            $this->nomjoueur = $d['nomjoueur'];
            $this->place = $d["place"];
            //$this->uno = $d["uno"];
            $this->token = $d["token"];
        } else {
            $this->token = md5("CeUnoEstGénialEtJeSuisContent" . $nomjoueur);
            $this->nomjoueur = $nomjoueur;
            log_it(__METHOD__, 1);
            if (mysql_query("insert into joueur values('$nomjoueur',-1,'$this->token',0,0,null, " . time() . ");")) {
                log_it("Réussis", 0);
            } else {
                log_it("ECHEC : " . mysql_error(), 0);
            }
            log_it("/" . __METHOD__, -1);
        }
    }

    /**
     *  Retourne le Token, généré par la création dans la Bdd
     * @return string 
     */
    public function getToken() {
        return $this->token;
    }

    /**
     *  Récupère un joueur en fonction d'un token
     * @param string $token token passé par Ajax
     * @param SQLite_resource $db DB SQLite
     * @return Joueur Joueur ayant le token $token
     */
    public static function getJoueur($token, $db) {
        log_it(__METHOD__, 1);
        if ($token == "") {
            log_it("Token null", 0);
            log_it("/" . __METHOD__, -1);
            return null;
        }
        $q = mysql_query("
            SELECT * FROM joueur
            WHERE token='$token'");
        if ($q && $d = mysql_fetch_array($q)) {
            log_it("Joueur trouvé ({$d["nomjoueur"]})", 0);
            log_it("/" . __METHOD__, -1);
            return new Joueur($d["nomjoueur"], $db);
        } else {
            log_it("(Non trouvé)", 0);
            log_it("/" . __METHOD__, -1);
            return null;
        }
    }

    /**
     *  Permet de lier la partie $p au Joueur
     * @param Partie $p
     * @return boolean true si ca a fonctionné, False sinon.
     * False est retourné si le joueur est déjà dans une partie ou si la partie est pleine 
     */
    public function lierPartie(Partie $p) {
        log_it(__METHOD__, 1);
        if ($p->getIdPartie() == null) {
            log_it("/" . __METHOD__, -1);
            return false;
        }
        if ($this->idpartie != null && ($this->idpartie != $p->getIdPartie() || $p->getDebut())) {
            log_it("/" . __METHOD__, -1);
            return false;
        }
        if ($this->idpartie != null) {
            log_it("/" . __METHOD__, -1);
            return true;
        }
        if (sizeof($p->getJoueurs()) > 3) {
            log_it("/" . __METHOD__, -1);
            return false;
        }
        $joueurs=$p->getJoueurs();
        $place = -1;
        $a=0;
        while ($place == -1 && $a<=sizeof($joueurs)){
            if(!isset($joueurs[$a]))
                $place=$a;
            $a++;
        }
        //$place = sizeof($p->getJoueurs());
        log_it("Idpartie : " . $p->getIdPartie(), 0);
        log_it("Place : " . $place, 0);
        $err = mysql_query("
            UPDATE joueur
                SET idpartie=" . $p->getIdPartie() . ", place =$place
                WHERE nomjoueur='$this->nomjoueur'");
        $this->place=$place;
        log_it("SQL($err) : " . mysql_error(), 0);
        $this->idpartie = $p->getIdPartie();
        log_it("/" . __METHOD__, -1);
        return Evenement::create("nouveau_joueur", $this, $p, $this->nomjoueur);
        ;
    }

    public function delierPartie() {
        log_it(__METHOD__, 1);
        $p = $this->getPartie();
        if ($p == null || $p->getIdPartie() == null) {
            log_it("(Joueur pas dans une partie)", 0);
            log_it("/" . __METHOD__, -1);
            return false;
        }
        log_it("Partie trouvée (" . json_encode($p->toarray()) . ")", 0);
        mysql_query("
            UPDATE joueur
                SET idpartie=null, place=null
                WHERE nomjoueur='$this->nomjoueur'");
        $this->idpartie = null;
        $position = $this->getPosition();
        if (sizeof($p->getJoueurs()) != 0) {
            Evenement::create("supprimer_joueur", $position, $p, $this->nomjoueur);
        } else {
            $p->delete();
        }
        log_it("/" . __METHOD__, -1);
        return true;
    }

    /**
     * Met a jour le Timestamp d'un joueur afin de reperer les joueurs inactifs
     */
    public function update() {
        log_it(__METHOD__ . "($this->nomjoueur)", 0);
        mysql_query("
            UPDATE joueur
                SET timestamp=" . time() . "
                WHERE nomjoueur='$this->nomjoueur'");
    }

    /**
     * Supprime les joueurs qui sont inactifs depuis plus de 5 minute entière.
     */
    public static function nettoyer($db) {
        $q = mysql_query("
            SELECT * FROM joueur
                WHERE timestamp<'" . (time() - ( 5 * 60 )) . "'");
        //
        while ($q && $d = mysql_fetch_array($q)) {
            $joueur = new Joueur($d["nomjoueur"], $db);
            $joueur->delierPartie();
        }
        mysql_query("
            DELETE FROM joueur
                WHERE timestamp<'" . (time() - ( 5 * 60 )) . "'");
    }

    public static function disconnect($db) {
        $q = mysql_query("
            SELECT * FROM joueur
                WHERE timestamp<'" . (time() - ( 60 )) . "'");
        while ($q && $d = mysql_fetch_array($q)) {
            $j = new Joueur($d["nomjoueur"], $db);
            $j->delierPartie();
        }
    }

    /**
     *  Recupere la partie
     * @return Partie partie 
     */
    public function getPartie() {
        return new Partie(intval($this->idpartie), $this->db);
    }

    /**
     *  retourne la position du joueur dans la partie
     * @return int position 
     */
    public function getPosition() {
        //return $this->getPartie()->getPositionJoueur($this);
        return $this->place;
    }
    
    /**
     * Getter sur $nomjoueur
     * @return String nom du joueur
     */
    public function getNom() {
        return $this->nomjoueur;
    }

    /**
     *  Teste si le joueur portant ce nom existe
     * @param string $nomjoueur Nom a tester
     * @return boolean 
     */
    static public function exists($nomjoueur, $db) {
        $nomjoueur = mysql_real_escape_string($nomjoueur);
        $jrs = mysql_query("Select * from joueur where nomjoueur='$nomjoueur'");
        if ($jrs && mysql_fetch_array($jrs)) {
            return true;
        }
        return false;
    }

    /**
     * 
     */
    public function toarray() {
        $r = array();
        $r["nom_joueur"] = $this->nomjoueur;
        if ($this->idpartie != null) {
            $r["partie"] = $this->getPartie()->toarray();
            $r["place"] = $this->getPosition();
        }
        return $r;
    }

    /**
     *  Créée un evenement de deplacement de carte de la pioche a la main du joueur;
     * @return string carte
     */
    public function piocher() {
        log_it(__METHOD__, 1);
        $partie = $this->getPartie();
        log_it("Partie : {$partie->getIdPartie()}", 0);
        $carte = $partie->getCartePioche();
        log_it("Carte : $carte", 0);
        Evenement::create("mouvement_carte", $this, $partie, $carte);
        log_it("($carte)", 0);
        log_it("/" . __METHOD__, -1);
        return $carte;
    }

    /**
     *  cartes de la main d'un joueur<br>
     * Pour avoir le nb de carte, il faut faire sizeof($joueur->getCartes())
     * @return array<String> Cartes 
     */
    public function getCartes() {
        $partie=  $this->getPartie();
        log_it(__METHOD__, 1);
        $r = array();
        $q = mysql_query("
            SELECT * FROM evenement
            WHERE type='mouvement_carte' AND idpartie=$this->idpartie AND destination=" . $this->getPosition() . " ORDER BY idevenement DESC");
        while ($q && $d = mysql_fetch_array($q)) {
            if ($partie->getPositionCarte($d["data"]) == $this->place) {
                log_it("Carte++", 0);
                $r[] = $d["data"];
            }
        }
        log_it("/" . __METHOD__, -1);
        return $r;
    }

    public function isContreUnoable() {
        if (sizeof($this->getCartes()) != 1)
            return false;
        $q1 = mysql_query("
            SELECT * FROM evenement
            WHERE type='event_uno' AND idpartie=$this->idpartie AND destination=" . $this->getPosition() . " ORDER BY idevenement DESC LIMIT 1");
        if ($q1 && $d1 = mysql_fetch_array($q1)) {
            $q1 = mysql_query("
            SELECT * FROM evenement
            WHERE type='mouvement_carte' AND idpartie=$this->idpartie AND destination=" . $this->getPosition() . " AND idevenement>{$d1["idevenement"]} ORDER BY idevenement DESC LIMIT 1");
            if ($q1 && $d1 = mysql_fetch_array($q1))
                return false;
            return true;
        }
        return true;
    }
    
    public function poserCarte($carte) {
        log_it(__METHOD__, 1);
        $partie=$this->getPartie();
        if ($partie->isPosable($this, $carte)) {
            Evenement::create("mouvement_carte", 5, $partie, $carte);
            if (carte::getCouleur($carte) == "S") {
                Evenement::create("choisir_couleur", $this, $partie, '');
            }
            if (carte::getValeur($carte) == "I") {
                $partie->inverserSens();
            }
            if (carte::getValeur($carte) == "P") {
                $partie->toursSuivant();
            }
            $partie->toursSuivant();
            log_it("Carte posée", 0);
            log_it("/" . __METHOD__, -1);
            if(sizeof($this->getCartes())==0){
                $partie->finPartie($this);
            }
            return true;
        } else {
            log_it("Carte non posable", 0);
            log_it("/" . __METHOD__, -1);
            return false;
        }
    }

}

